package com.mao.filter;

import com.mao.security.TokenManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class TokenAuthenticationFilter extends BasicAuthenticationFilter {

    private TokenManager tokenManager;
    private RedisTemplate redisTemplate;


    public TokenAuthenticationFilter(AuthenticationManager authenticationManager,TokenManager tokenManager,RedisTemplate redisTemplate) {
        super(authenticationManager);
        this.tokenManager = tokenManager;
        this.redisTemplate = redisTemplate;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取当前认证成功 用户的权限信息
       UsernamePasswordAuthenticationToken authRequest = getAuthentication(request);

        //判断是否有权限信息 放到权限的上下文中
        if (authRequest != null){
            SecurityContextHolder.getContext().setAuthentication(authRequest);
        }

        chain.doFilter(request,response);

    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
        // 从header中获取token
        String token = request.getHeader("token");

        if (token != null){
            // 从token中获取用户名
            String username = tokenManager.getUserInfoToken(token);

            // 从redis中获取对应的 权限列表
            List<String> permissionValueList = (List<String>) redisTemplate.opsForValue().get(username);


            //Collection<? extends GrantedAuthority>
            Collection<GrantedAuthority> authorities = new ArrayList<>();

            for (String permissionValue : permissionValueList) {
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permissionValue);
                authorities.add(simpleGrantedAuthority);

            }

            return new UsernamePasswordAuthenticationToken(username,token,authorities);
        }

        return null;
    }
}
